package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserVipServiceMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidAlbumService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.service.VipServiceConfigService;
import com.atguigu.tingshu.user.strategy.StrategyFactory;
import com.atguigu.tingshu.user.strategy.StrategyMap;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private KafkaService kafkaService;

	@Autowired
	private UserPaidTrackService userPaidTrackService;

	@Autowired
	private UserPaidAlbumService userPaidAlbumService;

	@Autowired
	private AlbumFeignClient albumFeignClient;

	@Autowired
	private VipServiceConfigService vipServiceConfigService;

	@Autowired
	private UserVipServiceMapper userVipServiceMapper;

	@Autowired
	private StrategyMap strategyMap;

	@Override
	public Map<String, String> wxLogin(String code) {
		try {
			// 调用第三方集成的SDK获取openid

			WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
			String openid = sessionInfo.getOpenid();

			if(openid != null){
				//根据微信唯一标识查询用户记录
				QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
				userInfoQueryWrapper.eq("wx_open_id",openid);
				UserInfo userInfo = userInfoMapper.selectOne(userInfoQueryWrapper);

				// 如果没有则初始化用户信息,说明是首次登录
				if(userInfo == null){

					//2.2 为首次登录用户构建用户对象，保存用户记录
					userInfo = new UserInfo();
					userInfo.setWxOpenId(openid);
					userInfo.setNickname("听友" + IdUtil.getSnowflakeNextId());
					userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
					userInfo.setIsVip(0);
					userInfoMapper.insert(userInfo);
					//2.3 TODO 发送Kafka异步消息，通知账户微服务新增账户记录
					kafkaService.sendMessage(KafkaConstant.QUEUE_USER_REGISTER,userInfo.getId().toString());
				}

				// 如果存在，则把用户信息放入redis，并返回token给前端
				String token = IdUtil.getSnowflakeNextIdStr();
				String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;

				//排除掉用户隐私数据
				UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
				redisTemplate.opsForValue().set(loginKey, userInfoVo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);

				HashMap<String, String> resultMap = new HashMap<>();
				resultMap.put("token",token);
				return resultMap;
			}
			return null;
		}catch (Exception e){
			log.error("[用户服务]微信登录异常：{}", e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public UserInfoVo getUserInfo(Long userId) {
		UserInfo userInfo = userInfoMapper.selectById(userId);
		UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
		return userInfoVo;
	}

	@Override
	public void  updateUser(Long userId, UserInfoVo userInfoVo) {
		UserInfo userInfo = BeanUtil.copyProperties(userInfoVo, UserInfo.class);
		userInfo.setId(userId);
		userInfoMapper.updateById(userInfo);
	}


	@Override
	public Boolean isPaidAlbum(Long albumId) {
		Long userId = AuthContextHolder.getUserId();

		LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(UserPaidAlbum::getAlbumId,albumId);
		wrapper.eq(UserPaidAlbum::getUserId,userId);
		long count = userPaidAlbumService.count(wrapper);

		return count > 0;
	}

	@Override
	public List<Long> findUserPaidTrackList(Long albumId,Long userId) {
		QueryWrapper<UserPaidTrack> wrapper = new QueryWrapper<>();
		wrapper.eq("user_id",userId);
		wrapper.eq("album_id",albumId);
		List<UserPaidTrack> list = userPaidTrackService.list(wrapper);
		if(CollectionUtil.isNotEmpty(list)){
			return list.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
		}
		return Collections.emptyList();
	}

	@Override
	public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needChackTrackIdList) {

		// 根据用户id和专辑id查询用户是否购买了专辑
		LambdaQueryWrapper<UserPaidAlbum> userPaidAlbumLambdaQueryWrapper = new LambdaQueryWrapper<>();
		userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getUserId,userId);
		userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getAlbumId,albumId);
		UserPaidAlbum userPaidAlbum = userPaidAlbumService.getOne(userPaidAlbumLambdaQueryWrapper);


		Map<Long, Integer> resultMap = new HashMap<>();

		// 如果购买将待检查声音列表购买情况都设置为 1
		if (userPaidAlbum != null){
			for (Long check : needChackTrackIdList) {
				resultMap.put(check,1);
			}
			return resultMap;
		}

		// 如果为空，则查询 user_paid_track 是否有匹配的
		LambdaQueryWrapper<UserPaidTrack> userPaidTrackLambdaQueryWrapper = new LambdaQueryWrapper<>();
		userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getUserId,userId);
		userPaidTrackLambdaQueryWrapper.in(UserPaidTrack::getTrackId,needChackTrackIdList);
		List<UserPaidTrack> userPaidTrackList = userPaidTrackService.list(userPaidTrackLambdaQueryWrapper);


		// 如果不存在，则全部设置为0
		if (CollectionUtil.isEmpty(userPaidTrackList)) {
			for (Long check : needChackTrackIdList) {
				resultMap.put(check,0);
			}
			return resultMap;
		}


		// 匹配已购买的声音
		List<Long> bugouht = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());

		for (Long check : needChackTrackIdList) {
			if(bugouht.contains(check)){
				resultMap.put(check,1);
			}else{
				resultMap.put(check,0);
			}
		}
		return resultMap;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void savePaidRecord(UserPaidRecordVo userPaidRecordVo) {
		StrategyFactory strategy = strategyMap.getStrategy(userPaidRecordVo.getItemType());
		strategy.savePaidRecord(userPaidRecordVo);

//		if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)){
//			// 保存专辑
//
//			// 重复提交调用,导致重复保存,所以先利用订单号(唯一性)查询数据库
//			LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
//			wrapper.eq(UserPaidAlbum::getOrderNo,userPaidRecordVo.getOrderNo());
//			long count = userPaidAlbumService.count(wrapper);
//			if(count > 0) return;
//
//			// 保存已购专辑
//			UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
//			userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
//			userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
//			userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
//			userPaidAlbumService.save(userPaidAlbum);
//
//		}else if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)){
//			// 保存声音
//
//			// 重复提交调用,导致重复保存,所以先利用订单号(唯一性)查询数据库
//			LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
//			wrapper.eq(UserPaidTrack::getOrderNo,userPaidRecordVo.getOrderNo());
//			long count = userPaidTrackService.count(wrapper);
//			if(count > 0) return;
//
//			TrackInfo trackInfo = albumFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0)).getData();
//			Long albumId = trackInfo.getAlbumId();
//
//
//			List<UserPaidTrack> userPaidTrackList = new ArrayList<>();
//			userPaidRecordVo.getItemIdList().forEach(new Consumer<Long>() {
//				@Override
//				public void accept(Long trackId) {
//					UserPaidTrack userPaidTrack = new UserPaidTrack();
//					userPaidTrack.setUserId(userPaidRecordVo.getUserId());
//					userPaidTrack.setTrackId(trackId);
//					userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
//					userPaidTrack.setAlbumId(albumId);
//					userPaidTrackList.add(userPaidTrack);
//				}
//			});
//			userPaidTrackService.saveBatch(userPaidTrackList);
//
//		}else if(userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_VIP)){
//			// VIP
//			// 重复提交调用,导致重复保存,所以先利用订单号(唯一性)查询数据库
//			LambdaQueryWrapper<UserVipService> wrapper = new LambdaQueryWrapper<>();
//			wrapper.eq(UserVipService::getOrderNo,userPaidRecordVo.getOrderNo());
//			Long count = userVipServiceMapper.selectCount(wrapper);
//			if(count > 0) return;
//
//			//根据VIP套餐ID查询套餐信息-得到VIP会员服务月数
//			Long vipConfigId = userPaidRecordVo.getItemIdList().get(0);
//			VipServiceConfig vipServiceConfig = vipServiceConfigService.getById(vipConfigId);
//			Integer serviceMonth = vipServiceConfig.getServiceMonth();
//
//			// 查询用户是否为VIP，是则延长事件，不是则新增
//			UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
//			Integer isVip = userInfo.getIsVip();
//			Date vipExpireTime = userInfo.getVipExpireTime();
//
//			// VIP记录表
//			UserVipService userVipService = new UserVipService();
//			userVipService.setUserId(userPaidRecordVo.getUserId());
//			userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
//
//			if(isVip == 1 && vipExpireTime.after(new Date())){
//				userVipService.setStartTime(vipExpireTime);
//				userVipService.setExpireTime(DateUtil.offsetMonth(vipExpireTime,serviceMonth));
//			}else {
//				userVipService.setStartTime(new Date());
//				userVipService.setExpireTime(DateUtil.offsetMonth(new Date(),serviceMonth));
//			}
//			// 保存VIP订单记录
//			userVipServiceMapper.insert(userVipService);
//			// 更新用户记录
//			userInfo.setVipExpireTime(userVipService.getExpireTime());
//			userInfo.setIsVip(1);
//			userInfoMapper.updateById(userInfo);
//		}

	}
}
























